home *** CD-ROM | disk | FTP | other *** search
/ PsL Monthly 1993 December / PSL Monthly Shareware CD-ROM (December 1993).iso / prgmming / dos / c / bor_ti.exe / TI1036.ASC < prev    next >
Text File  |  1992-10-23  |  9KB  |  331 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6.  
  7.  
  8.   PRODUCT  :  Borland C++                           NUMBER  :  1036
  9.   VERSION  :  3.1
  10.        OS  :  DOS
  11.      DATE  :  October 23, 1992                         PAGE  :  1/5
  12.  
  13.     TITLE  :  Determining the amount of stack used at runtime.
  14.  
  15.  
  16.  
  17.  
  18.  
  19.        The following program provides an example on how to
  20.   determine how the amount of stack not being used by an
  21.   application.  The example also determine the amount of the near
  22.   heap that has been
  23.    used.
  24.  
  25.        This is accomplished by making a call at the beginning of
  26.   the program to a function that will mark all of the stack space
  27.   not currently in use with the character 0xFF.  Just before the
  28.   program exits, a call is made to another function that will count
  29.   the number of unchanged 0xFF bytes on the stack.  When trying to
  30.   determine the amount of the near heap that was used calloc should
  31.   be used rather than malloc to allocate the memory because calloc
  32.   will initialize the memory allocated to all zeros so it will
  33.   later be apparent that that memory was allocated even if the
  34.   values were never changed.
  35.  
  36.        This method is not a 100% guaranteed one, but it will work
  37.   most of the time.  Its reliablity can be determined by
  38.   understanding how it performs its task and what problems that may
  39.   inccur with a particular program.  For instance it may prove
  40.   necessary to change the character used to mark the unused stack
  41.   space.  It is also important to note that when attempting to
  42.   change the stack size in a near memory model one must change the
  43.   value of _heaplen or DGROUP will always be 64K regardless of the
  44.   value of _stklen.
  45.  
  46.        In order to use these function you need to place the
  47.   following prototypes in the source file you will be calling them
  48.   from:
  49.             void init_stack_count(void);
  50.             void stack_count(void);
  51.        To determine the amount of unused stack you must first make
  52.   an initial call to:
  53.                  init_stack_count();
  54.   at the beginning of the program and just before exiting the
  55.   program  another call is required to:
  56.                  stack_count();
  57.        The amount of unused stack space will be printed on the
  58.   screen.  If you need to determine the amount of the near heap
  59.   used in order to adjust the stack in the near memory model then
  60.  
  61.  
  62.  
  63.  
  64.  
  65.  
  66.  
  67.  
  68.  
  69.  
  70.  
  71.  
  72.  
  73.  
  74.   PRODUCT  :  Borland C++                           NUMBER  :  1036
  75.   VERSION  :  3.1
  76.        OS  :  DOS
  77.      DATE  :  October 23, 1992                         PAGE  :  2/5
  78.  
  79.     TITLE  :  Determining the amount of stack used at runtime.
  80.  
  81.  
  82.  
  83.  
  84.   the symbol _HEAP_ must be defined in this module.  You can do
  85.   this by adding the statement:
  86.             #define _HEAP_
  87.        at file scope (outside any function definition) in this
  88.   source file.  Then this souce file must be compiled and linked
  89.   into your program as if it were any other module in your program.
  90.  
  91.  
  92.  
  93.   #include <stdio.h>
  94.   #include <process.h>
  95.   #include <conio.h>
  96.   #include <dos.h>
  97.   #include <alloc.h>
  98.  
  99.   #define SIZE_OF_EMULATOR 415            // Account for floating
  100.                                           // point emulator
  101.   #define FILL_CHAR 0xFF                  // Character used to mark
  102.                                           // the stack
  103.  
  104.   #pragma warn -aus                       // Turn off unecessary
  105.   #pragma warn -use                       // warnings
  106.  
  107.  
  108.  
  109.   / ************************************************************* \
  110.   |    Marks all possible stack space not currently in use by     |
  111.   |    setting the values   to 0xff.                              |
  112.   \ ************************************************************* /
  113.   void init_stack_count(void)
  114.   {
  115.        char far *sp;                 // far memory model stack
  116.                                      // pointer
  117.        char near *nsp;               // near memory model stack
  118.                                      // pointer
  119.        extern  unsigned __brklvl;    // Internal variable marking
  120.                                      // top of
  121.                                      // the near heap.
  122.  
  123.   #if  defined(__COMPACT__)     ||   \
  124.        defined(__LARGE__)       ||   \
  125.        defined(__HUGE__)
  126.   #undef    _HEAP_
  127.  
  128.  
  129.  
  130.  
  131.  
  132.  
  133.  
  134.  
  135.  
  136.  
  137.  
  138.  
  139.  
  140.   PRODUCT  :  Borland C++                           NUMBER  :  1036
  141.   VERSION  :  3.1
  142.        OS  :  DOS
  143.      DATE  :  October 23, 1992                         PAGE  :  3/5
  144.  
  145.     TITLE  :  Determining the amount of stack used at runtime.
  146.  
  147.  
  148.  
  149.  
  150.        sp = MK_FP( _SS, _SP - 1 );   // initialize sp to point to
  151.                                      // the next available space on
  152.                                      // the stack.
  153.  
  154.        while( sp > (char far *)SIZE_OF_EMULATOR ) //Check
  155.                                      // for stack overflow
  156.        {
  157.             *sp = FILL_CHAR;         // Initialize unused stack
  158.                                      // space
  159.             sp--;
  160.        }
  161.   #else                              // similar for near data
  162.                                      // memory model
  163.        nsp = (char *) _SP - 1;       // Initialize pointer
  164.        while( nsp > (char *)__brklvl)// Check for stack overflow
  165.        {
  166.             *nsp = FILL_CHAR;        // Assign fill character
  167.             nsp--;                   // advance pointer
  168.        }
  169.   #endif
  170.        return;
  171.   }
  172.  
  173.  
  174.  
  175.   / ************************************************************* \
  176.   |    Goes though stack space counting unused (unmodified)       |
  177.   |    values meaning that space on the stack was not used.       |
  178.   \ ************************************************************* /
  179.   void stack_count( void )
  180.   {
  181.        unsigned count= 0;            // Amount of unused stack
  182.                                      // space
  183.        unsigned mcount = 0;          // Amount of used Heap space
  184.        char far *sp;                 // Far memory model pointer
  185.        char *nsp;                    // Near memory model pointer
  186.  
  187.  
  188.   #if  defined(__COMPACT__)     ||   \
  189.        defined(__LARGE__)       ||   \
  190.        defined(__HUGE__)
  191.  
  192.        sp = MK_FP( _SS, SIZE_OF_EMULATOR+1);   // Initialize the
  193.  
  194.  
  195.  
  196.  
  197.  
  198.  
  199.  
  200.  
  201.  
  202.  
  203.  
  204.  
  205.  
  206.   PRODUCT  :  Borland C++                           NUMBER  :  1036
  207.   VERSION  :  3.1
  208.        OS  :  DOS
  209.      DATE  :  October 23, 1992                         PAGE  :  4/5
  210.  
  211.     TITLE  :  Determining the amount of stack used at runtime.
  212.  
  213.  
  214.  
  215.  
  216.                                                // pointer
  217.        if( _SP >  SIZE_OF_EMULATOR )           // Check for stack
  218.                                                // overflow
  219.        {
  220.             while( sp < MK_FP(_SS,_SP)  )      // Check for stack
  221.                                                // overflow
  222.             {
  223.                  if( *sp != (char) FILL_CHAR ) // compare pointer
  224.                                                //value to
  225.                                                // fill character
  226.                       break;
  227.                  count++;                      // count unused
  228.                                                // stack space
  229.                  sp++;                         // increment pointer
  230.             }
  231.        }
  232.   #else
  233.        extern unsigned __brklvl;          // End of near heap
  234.        extern unsigned __heapbase;        // Beginning of near heap
  235.        if( _SP > __brklvl  )              // Check for stack
  236.                                           // overflow
  237.        {
  238.             nsp = (char *) __brklvl + 1;
  239.             while( nsp < (char *)_SP )    // While we don't run
  240.                                           // into the
  241.                                           // current stack.
  242.             {
  243.                  if( *nsp != (char) FILL_CHAR && count < 3)
  244.                                           // Count near heap used
  245.                       mcount++;
  246.                                           // else count unused
  247.                                           // stack
  248.                  else if( *(nsp + 1) == (char)FILL_CHAR &&
  249.                           *(nsp + 2) == (char) FILL_